package com.keter.dtx.service.tcc.impl;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.keter.dtx.service.tcc.ResultHolder;
import com.keter.dtx.service.tcc.TccActionTwo;
import io.seata.rm.tcc.api.BusinessActionContext;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * The type Tcc action two.
 *
 * @author zhangsen
 */
@Component
public class TccActionTwoImpl implements TccActionTwo {

    private static final Logger logger = LoggerFactory.getLogger(TccActionTwoImpl.class);

    @Override
    public boolean prepare(BusinessActionContext context, String name) {
        logger.info("对于Insert业务Prepare操作无须执行任何内容！");
        logger.info("TccAction2 PREPARE, xid:{}, actionName:{}, name:{}",
                context.getXid(),
                context.getActionName(),
                context.getActionContext("name"));
        return true;
    }

    /**
     * 模拟插入操作
     * @param context the action context
     * @return
     */
    @Override
    public boolean commit(BusinessActionContext context) {
        // 从上下文中获取传递的业务参数
        String name = (String) context.getActionContext("name");
        Validate.notEmpty(name);
        //修改 action_one 记录
        Record r = new Record().set("name",name);
        Db.save("action_two",r);
        logger.info("TccAction2 COMMIT - xid:{}, name:{}, recordId:{}", context.getXid(), name,r.getInt("id"));
        //保存新增记录用于回滚：但只有提交成功后才能得到回滚数据
        ResultHolder.setResult(context, r);
        return true;
    }

    //TODO:需要进一步了解TCC回滚失败时自动重试策略等机制
    @Override
    public boolean rollback(BusinessActionContext context) {
        Record r = ResultHolder.getResult(context);
        if(r==null){
            logger.info("空回滚：TccActionTwo事务尚未提交！");
            return true;
        }
        int id = r.getInt("id");
        logger.info("TccAction2 ROLLBACK - xid:{}, id:{}", context.getXid(), id);
        //使用新增数据的ID删除记录
        Db.update("delete action_two where id=?", id);
        return true;
    }
}
